<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>01_Vue的生命周期</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app" class="aaa">
      <ul id="myUl">
        <li v-for="(item, ind) in arr">{{item}}</li>
      </ul>
      <button @click="() => {arr.push(111)}">增加一个元素</button>

      <hr />
      <child-com v-if="isShow"></child-com>
    </div>
    <script>
      new Vue({
        // 0. new Vue() 实例化Vue对象
        el: '#app', // el和$mount选择一个, 告诉Vue那个标签内部是它要解析的模板语法
        data: {
          msg: '我是变量',
          arr: [1, 2, 3, 4],
          isShow: true
        },
        beforeCreate() {
          // 1. data和methods创建前
          console.log('beforeCreate --- 实例化后, 数据变量初始化之前')
          console.log(this.msg) // undefined
        },
        created() {
          // 2. data, methods, 计算属性, 创建完毕
          console.log('created --- 实例化后, 被注入vue对象 之后')
          console.log(this.msg)
        },
        // 如果有el使用, 没有就找$mount (如果都没有vue不工作)
        // 如果有template, 使用tempmlate里的标签作为模板, 如果没有el#app这个里面的标签作为模板
        // 虚拟DOM(内存DOM): 你在html写的都是模板代码(不会真正被浏览器解析执行)
        // 被vue读取, 内存中生成一个dom树跟你的html写的标签结构一样的(遇到循环多次创建v-for所在标签)
        // 原因: 操作真实的DOM, 获取读取到内存中 才是操作,  虚拟DOM直接就再内存中可以直接操作(快)
        beforeMount() {
          // 3. 挂载前
          console.log('beforeMounte --- vue的虚拟DOM, 挂载到真实的网页之前(el) ')
          // console.log(document.getElementById("myUl").children[1].innerHTML); // 报错
        },
        mounted() {
          // 4. 挂载后
          console.log('mounted --- vue的虚拟DOM已经替换到了真实的网页上(el) ')
          console.log(document.getElementById('myUl').children[1].innerHTML)
        },
        beforeUpdate() {
          // 5. 更新前
          console.log('beforeUpdate --- data里数据更新后, 页面更新前触发')
          // console.log(document.getElementById("myUl").children[4].innerHTML); // 报错
        },
        updated() {
          // 6. 更新后
          console.log(
            'updated --- 虚拟DOM 重新渲染 真实网页后 (刷新变化的部分) '
          )
          console.log(document.getElementById('myUl').children[4].innerHTML)
        },
        errorCaptured() {
          // 9. 捕获子组件异常
          // 当子组件报错了, 此方法就会执行
          console.log('errorCaptured --- 子组件报错了')
        },
        components: {
          ChildCom: {
            template: `<div>我是子组件</div>`,
            beforeDestroy() {
              // 7. 销毁之前
              console.log('beforeDestroy --- 当前对象, 被销毁之前触发')
            },
            destroyed() {
              // 8. 销毁后
              // 在最后弥留之际, 触发一次此方法
              // (清空一些本地变量 / 全局变量 / 引用的全局事件)
              console.log('destroyed --- 销毁完成')
            },
            mounted() {
              throw new Error('假装子组件报错了') // throw抛出异常错误
            }
          }
        }
      })

      // 注意1: 不光new Vue中可以使用生命周期函数, 组件里也可以使用
      // 注意2: CSS手段隐藏标签, 不算销毁组件(只要从DOM上移除了, 才算销毁组件)

      // Vue世界里, 你在div#app 内写的东西, 都叫标签模板 -> 目的 -> 告诉Vue如何生成虚拟DOM
      // 虚拟DOM: 和指定的模板 结构 一模一样的 DOM标签, (存在于内存变量上) (真实的document获取/添加)
      // 为什么要有虚拟DOM:因为操作内存 会比 操作 真实的DOM元素 要快.

      // 最终, 要把虚拟DOM  替换到  真实的DOM上, 才会显示在网页上.

      // 创建  挂载  更新  激活  销毁           捕获
      // 创建 -> beforeCreate created
      // 挂载 -> beforeMount mounted
      // 更新 -> beforeUpdate updated
      // 激活 -> activated deactivated
      // 销毁 -> beforeDestroy destroyed


      
      // 捕获 -> vue2.5+  errorCaptrued
    </script>
  </body>
</html>
